package com.shuyuntu.proposal.security;

import com.shuyuntu.proposal.dao.IDelegateDao;
import com.shuyuntu.proposal.entity.Delegate;
import com.shuyuntu.proposal.entity.Permission;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Created by limeng on 16/8/15.
 */
public class SecurityHolder {
    public void permissionCheck(HttpSession session, UseSecurity annotation) throws Exception {
        try {
            if (annotation == null) {
                return;
            }

            if (session == null) {
                throw makeException(annotation);
            }

            String delegateId = (String) session.getAttribute("loginUserId");

            if (delegateId == null) {
                throw makeException(annotation);
            }

            //TODO:这里具有优化的余地!
            Delegate delegate = delegateDao.queryById(delegateId);

            Set<Permission> permissionSet = delegate.getRole().getPermissions();
            Set<String> permissionCategorySet = new HashSet<>();
            for (Permission permission : permissionSet) {
                permissionCategorySet.add(permission.getCategory());
            }

            Set<String> categorySet = new HashSet<>();
            Collections.addAll(categorySet, annotation.category());

            //取交集,如果有交集的话,说明当前权限包含其中
            permissionCategorySet.retainAll(categorySet);

            if (permissionCategorySet.size() > 0) {
                return;
            }
        } catch (ClassCastException e) {
            e.printStackTrace();
            throw e;
        }

        throw makeException(annotation);
    }

    private RuntimeException makeException(UseSecurity annotation) {
        RuntimeException exception;
        if (annotation.toLogin()) {
            exception = new SecurityLoginException();
        } else {
            exception = new Security404Exception();
        }
        return exception;
    }

    @Resource
    IDelegateDao delegateDao;

    public IDelegateDao getDelegateDao() {
        return delegateDao;
    }

    public void setDelegateDao(IDelegateDao delegateDao) {
        this.delegateDao = delegateDao;
    }
}